<?php

namespace App\CustHub\Aspect;

use App\CustHub\Annotation\SaasVerifySignature;
use App\CustHub\Helpers\SaasSign;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
use Mine\Exception\NormalStatusException;
use Mine\MineRequest;
use Psr\Container\ContainerInterface;

#[Aspect]
class SaasVerifySignatureAspect extends AbstractAspect
{
    public array $annotations = [
        SaasVerifySignature::class
    ];

    /**
     * 容器
     */
    protected ContainerInterface $container;


    public function __construct()
    {
        $this->container = container();
    }

    public function process(ProceedingJoinPoint $proceedingJoinPoint)
    {
        $request = $this->container->get(MineRequest::class);

        //获取代理类 过滤掉不需要登录的方法
        $instance = $proceedingJoinPoint->getInstance();
        if(property_exists($instance,'noNeedVerifySign')){
            $noNeedVerifySign = $instance->noNeedVerifySign;
            $uri = $request->getUri();
            if ($uri->getPath() !== '/favicon.ico' && mb_substr_count($uri->getPath(), '/') > 1) {
                $pathArr = explode('/', $uri->getPath());
                $methodName = end($pathArr);
                if(in_array('*',$noNeedVerifySign) || in_array($methodName,$noNeedVerifySign)){
                    return $proceedingJoinPoint->process();
                }
            }
        }

        //时间戳校验
        $time =$request->header('x-time');
        if(time() - $time  > 60){
            throw new NormalStatusException('请求已过期');
        }

        $data = $request->all();
        $signStr = $request->header('x-sign');
        if(empty($signStr)){
            throw new NormalStatusException('签名校验失败，请检查签名加密方式"');
        }
        //签名校验
        $sign = new SaasSign();
        if(!$sign->checkSign($data,$signStr)){
            throw new NormalStatusException('签名校验失败，请检查签名加密方式"');
        }

        return $proceedingJoinPoint->process();
    }

}